#include "model/base/Graphic.hpp"
#include "model/Triangle.hpp"
#include "model/TD_XVertex.hpp"
#include "model/CurveBezier.hpp"
#include "view/CharScreen.hpp"
#include "utils/zui.h"

#include <cstdlib>
#include <iostream>

using namespace std;

void exp3(void) {
	model::CharTriangle
		t1(22, 13, 18, 38, 36, 28, '1'),
		t2(22, 13, 18, 38, 36, 28, '2'),
		t3(22, 13, 18, 38, 36, 28, '3'),
		t4(22, 13, 18, 38, 36, 28, '4'),
		t5(22, 13, 18, 38, 36, 28, '5');

	view::CharScreen cscreen(64, 46);

	cout<<"\n\n\n\n"<<"\t 实  验  三\n\n\t 兰  彦  真\n\t201883290546"<<flush;
	cin.get();
	cls;

	cout << "\n原三角形";
	cscreen.setGraphic(t1);
	cout << cscreen << flush;
	cin.get();
	cls;

	cout << "\n平移(3, -2)后";
	t2.translate(model::base::Graphic<char>::getPositionTranslate3x3F(3, -2));
	cscreen.setGraphic(t2);
	cout << cscreen << flush;
	cin.get();
	cls;

	cout << "\n缩放(1.5, 0.5)后";
	t3.translate(model::base::Graphic<char>::getScaleTranslate3x3F(1.5, 0.5));
	cscreen.setGraphic(t3);
	cout << cscreen << flush;
	cin.get();
	cls;

	cout << "\n旋转-0.5弧度后";
	t4.translate(model::base::Graphic<char>::getRotationTranslate3x3F(-0.5));
	cscreen.setGraphic(t4);
	cout << cscreen << flush;
	cin.get();
	cls;

	cout << "\n绕原点旋转-0.5弧度后";
	t5.translate(
		model::base::Graphic<char>::getPositionTranslate3x3F(22, 13) *
		model::base::Graphic<char>::getRotationTranslate3x3F(-0.5)  *
		model::base::Graphic<char>::getPositionTranslate3x3F(-22, -13)
	);
	cscreen.setGraphic(t5);
	cout << cscreen << flush;
	cin.get();
	cls;

	cout<<"\n\n\n\n\t演  示  结  束\n\n\t谢  谢  观  看"<<flush;
	cin.get();

	cls;
}

void exp4(void) {
	
	using model::base::Graphic;
	view::CharScreen cscreen(64, 46);

	/**构造一个正方体*/
	model::CharTD_XSides rectangle('o');
	rectangle.addSide(10, 10, 20, 20, 10, 20);
 	rectangle.addSide(20, 10, 20, 20, 10, 10);
	rectangle.addSide(20, 10, 10, 10, 10, 10);
	rectangle.addSide(10, 10, 10, 10, 10, 20);

	rectangle.addSide(10, 20, 20, 20, 20, 20);
 	rectangle.addSide(20, 20, 20, 20, 20, 10);
	rectangle.addSide(20, 20, 10, 10, 20, 10);
	rectangle.addSide(10, 20, 10, 10, 20, 20);

	rectangle.addSide(10, 10, 20, 10, 20, 20);
 	rectangle.addSide(20, 10, 20, 20, 20, 20);
	rectangle.addSide(20, 10, 10, 20, 20, 10);
	rectangle.addSide(10, 10, 10, 10, 20, 10);
	
	rectangle.exposure(
		utils::EasyMatrix<Float>(4, 4, {
			1.0, 0.0, 0.0, 0.0,
			0.0, 1.0, 0.0, 0.0,
			0.0, 0.0, 1.0, 0.0,
			0.0, 0.0, 0.0, 1.0
		})
	);
	cscreen.setGraphic(rectangle);
	cout << "正方体正投影" << endl << cscreen << endl;
	cin.get();
	//---------------
	rectangle.rotate(0.5F, 0.5F, 0.5F);
	cls;
	cscreen.clear();
	rectangle.exposure(
		utils::EasyMatrix<Float>(4, 4, {
			1.0, 0.0, 0.0, 0.0,
			0.0, 1.0, 0.0, 0.0,
			0.0, 0.0, 1.0, 0.0,
			0.0, 0.0, 0.0, 1.0
		})
	);
	cscreen.setGraphic(rectangle);
	cout << "正方体旋转 x=0.5 y=0.5 z=0.5（弧度）" << endl << cscreen << endl;
	cin.get();
	//---------------
	rectangle.transition(-5, 3, 3);
	cls;
	cscreen.clear();
	rectangle.exposure(
		utils::EasyMatrix<Float>(4, 4, {
			1.0, 0.0, 0.0, 0.0,
			0.0, 1.0, 0.0, 0.0,
			0.0, 0.0, 1.0, 0.0,
			0.0, 0.0, 0.0, 1.0
		})
	);
	cscreen.setGraphic(rectangle);
	cout << "正方体平移 x=-5 y=3 z=3" << endl << cscreen << endl;
	cin.get();
	//---------------
	rectangle.scale(2.4, 1.2, 1.0);
	cls;
	cscreen.clear();
 	rectangle.exposure(
 		utils::EasyMatrix<Float>(4, 4, {
 			1.0, 0.0, 0.0, 0.0,
 			0.0, 1.0, 0.0, 0.0,
 			0.0, 0.0, 1.0, 0.0,
 			0.0, 0.0, 0.0, 1.0
 		})
 	);
	cscreen.setGraphic(rectangle);
	cout << "正方体缩放 x=2.4 y=1.2 z=1.0" << endl << cscreen << endl;
	cin.get();
	//---------------
	cls;
	cscreen.clear();

	Float alpha = 1.2, beta = 1.4;

	Float sinAlpha = utils::FastMath::fastMath.sin(alpha);
	Float cosAlpha = utils::FastMath::fastMath.cos(alpha);
	Float tanBeta  = utils::FastMath::fastMath.tan(beta);
	
	rectangle.exposure(
		utils::EasyMatrix<Float>(4, 4, {
			1.0, 0.0, cosAlpha/tanBeta, 0.0,
			0.0, 1.0, sinAlpha/tanBeta, 0.0,
			0.0, 0.0, 1.0,              0.0,
			0.0, 0.0, 0.0,              1.0
		})
	);
	cscreen.setGraphic(rectangle);
	cout << "斜平行投影 alpha=1.2 beta=1.4" << endl << cscreen << endl;
	cin.get();
}

void exp5(void) {
	
	view::CharScreen cscreen(64, 46);
	using model::BezierCharCurve;
	
	BezierCharCurve bcurve1('1', {{1, 16}, {10, 38}, {7, 2}, {21, 27}});
	
	cscreen << bcurve1;
	cout << cscreen;

	cin.get();
	cls;
	// bcurve1 的最后两个控制点 (7,2) (21,27) 斜率为 25 / 14
	// 为了满足一阶连续，要让 bcurve2 的起始点为 (21,27)，
	//     第二个控制点在从起始点出发斜率为 25 / 14 的直线上
	// 故选取 (28,39.5) 作为 bcurve2 的第二个控制点
	BezierCharCurve bcurve2('2', {{21, 27}, {28, 39.5F}, {42, 2}, {54, 35}});
	cscreen << bcurve2;
	cout << cscreen;

	cin.get();
}

int main(void) {
	exp5();
	return 0;
}
